mod args;
mod logger;

use clap::Parser;
use rmcp::transport::sse_server::{SseServer, SseServerConfig};
use std::sync::Arc;
use tracing::{error, info};

use rmcp_gd::gd_handler::GdHandler;
use rmcp_gd::gd_manager::GdManager;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let args = args::Args::parse();

    logger::init();

    info!("====================[RMCP GD SSE]====================");

    let config = SseServerConfig {
        bind: format!("127.0.0.1:{}", &args.port).parse()?,
        sse_path: "/sse".to_string(),
        post_path: "/message".to_string(),
        ct: tokio_util::sync::CancellationToken::new(),
        sse_keep_alive: None,
    };

    let (sse_server, router) = SseServer::new(config);

    // Create godot manager
    let gd_manager = GdManager::new(&args.ws_url).map_err(|e| {
        error!("[sse] Failed to create gd manager: {}", e);
        anyhow::Error::msg(e.to_string())
    })?;

    let gd_manager = Arc::new(gd_manager);

    // Create gd handler
    let handler_creator = {
        error!("[sse] Clone gd handler");
        let gd_manager = gd_manager.clone();
        move || GdHandler::new(gd_manager.clone())
    };

    let listener = tokio::net::TcpListener::bind(sse_server.config.bind).await?;

    let ct = sse_server.config.ct.child_token();

    let server = axum::serve(listener, router).with_graceful_shutdown(async move {
        ct.cancelled().await;
        info!("[sse] Server cancelled");
    });

    tokio::spawn(async move {
        if let Err(e) = server.await {
            error!(error = %e, "[sse] Server shutdown with error");
        }
    });

    let ct = sse_server.with_service(handler_creator);

    tokio::signal::ctrl_c().await?;

    ct.cancel();

    info!("[sse] Server end");

    Ok(())
}
